call、apply、bind 都是 JavaScript 中用来显式改变函数运行时 this 指向的方法,它们都定义在 Function.prototype 上。三者的核心区别在于调用方式和传参形式。
1. call
- 立即执行函数。
- 第一个参数是 this 要指向的对象,后面的参数逐个传递。
func.call(thisArg, arg1, arg2, ...)
示例:
const obj = { name: 'Alice' };
function say(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
say.call(obj, 'Hello', '!'); // Hello, Alice!
2. apply
- 立即执行函数。
- 第一个参数是 this 要指向的对象,第二个参数是一个数组(或类数组),里面包含所有参数。
func.apply(thisArg, [arg1, arg2, ...])
示例:
say.apply(obj, ['Hi', '?']); // Hi, Alice?
- 经典使用场景:借用
Math.max处理数组。
Math.max.apply(null, [1, 5, 3]); // 5
3. bind
- 不会立即执行,而是返回一个绑定了 this 的新函数。
- 可以预设部分参数(柯里化),在真正调用时再传入剩余参数。
const boundFunc = func.bind(thisArg, arg1, arg2, ...)
boundFunc(restArgs...)
示例:
const sayToAlice = say.bind(obj, 'Hey');
sayToAlice('!!'); // Hey, Alice!!
- 典型使用场景:事件回调中固定 this,或延迟执行。
const user = {
name: 'Bob',
greet() { console.log('Hi, ' + this.name); }
};
setTimeout(user.greet.bind(user), 1000);
核心区别对比
| 特性 | call | apply | bind |
|---|---|---|---|
| 是否立即执行 | ✅ 是 | ✅ 是 | ❌ 否,返回新函数 |
| 参数传递方式 | 逐个传入 (comma-separated) | 以数组形式传入 | 可分批传入(预设+剩余) |
| 返回值 | 函数执行结果 | 函数执行结果 | 绑定了 this 的新函数 |
| 典型场景 | 明确参数个数时借用方法 | 参数已经是数组(如 Math.max) | 回调、事件监听、偏函数 |
简单记忆:
call—— Comma(逗号)传参,立即执行。apply—— Array(数组)传参,立即执行。bind—— Bind 之后不立即执行,返回新函数,传参类似 call。